import 'dart:async';
import 'dart:io';

///事件循环：（单线程，扔到队列中去）
//事件队列
//微任务队列（不放耗时多的，放优先级高的）
void main() {
  ///微任务 优先级 高于 Future(事件队列)
  // testFuture();

  ///练习，优先级
  // testFuture1();
  // testFuture2();

  // testFuture3();
  // testFuture4();
  testFuture5();
}

/**
 * 微任务 优先级 高于 Future(事件队列)
 *
 *  外部代码1
    外部代码2
    微任务
    A
    A结束
    B
    B结束
 */
void testFuture() {
  print('外部代码1');

  Future(() => print('A')).then((value) => print('A结束'));
  Future(() => print('B')).then((value) => print('B结束'));

  scheduleMicrotask(() {
    print('微任务');
  });
  sleep(Duration(seconds: 1));

  print('外部代码2');
}

/**
 *  5
    3
    1
    4
    2
 */
void testFuture1() {
  Future x = Future(() => print('1'));
  Future(() => print('2'));
  scheduleMicrotask(() {
    print('3');
  });
  x.then((value) => print('4'));
  print('5');
}

/**
 *  5
    3
    6
    1
    4
    2
 */
void testFuture2() {
  Future x1 = Future(() => null);
  Future x = Future(() => print('1'));
  Future(() => print('2'));
  scheduleMicrotask(() {
    print('3');
  });
  x.then((value) => print('4'));
  print('5');
  x1.then((value) => print('6'));
}

/**
 * 事件队列中有微任务，先执行then，then里面代码丢到了微任务队列
 * 5
    3
    6
    8
    7
    1
    4
    2
 */
void testFuture3() {
  Future x1 = Future(() => null);
  Future x2 = x1.then((value) {
    print('6');
    scheduleMicrotask(() => print('7'));
  });
  x2.then((value) => print('8'));

  Future x = Future(() => print('1'));
  x.then((value) => print('4'));

  Future(() => print('2'));

  scheduleMicrotask(() => print('3'));
  print('5');
}

/**  同上一个意思
 *  5
    3
    6
    8
    7
    1
    4
    2
 */
void testFuture4() {
  Future x1 = Future(() => null);
  Future x2 = x1.then((value) {
    print('6');
    scheduleMicrotask(() => print('7'));
  }).then((value) => print('8'));

  Future x = Future(() => print('1'));
  x.then((value) => print('4'));

  Future(() => print('2'));

  scheduleMicrotask(() => print('3'));
  print('5');
}

/**
 * then里面嵌套Future
 *
 *  3
    1
    4
    10
    2
    9
 */
void testFuture5() {
  Future x = Future(() => print('1'));
  x.then((value) {
    print('4');
    Future(() => print('9'));
  }).then((value) => print('10'));
  Future(() => print('2'));
  scheduleMicrotask(() => print('3'));
}
